home *** CD-ROM | disk | FTP | other *** search
/ Complete Linux / Complete Linux.iso / docs / apps / database / ingres04.lzh / source / ovqp / findsimps.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-09-18  |  7.3 KB  |  388 lines

  1. # include    <ingres.h>
  2. # include    <symbol.h>
  3. # include    <tree.h>
  4. # include    "../decomp/globs.h"
  5. # include    "strategy.h"
  6. # include    <sccs.h>
  7.  
  8. SCCSID(@(#)findsimps.c    8.4    4/13/85)
  9.  
  10. /*
  11. **    Findsimps searches the qualification for
  12. **    occurances of simple clauses. In its
  13. **    current crude implementation it only finds
  14. **    cluases of the form:
  15. **
  16. **    var relop constant  or  constant relop var
  17. **
  18. **    it does not use simple clauses with 'OR's
  19. **    nor does it accept clauses of the form
  20. **
  21. **    var relop constant + constant    etc.
  22. **
  23. **    Findsimps knows about pattern matching characters
  24. **    and treats char constants containing pm chars
  25. **    specially. For example
  26. **        var >= "xx*"  --> var >= "xx"
  27. **        var <= "xx*"  --> var <= "xx\0177"
  28. **        var =  "xx*"  --> var >= "xx" and var <= "xx\0177"
  29. **    If the first char is a pm char then the clause is not
  30. **    considered as a simple clause. Also notice that the conversion
  31. **    is done only once. If the next time De.ov_newq = FALSE, then findsimps()
  32. **    isn't called. This works because a pm char can only come from
  33. **    the user and not from a relation. Thus during tuple substition
  34. **    a constant with a pm will never change.
  35. */
  36.  
  37. findsimps()
  38. {
  39.     register struct symbol    *c;
  40.     register int        t;
  41.     int            length;
  42.     register struct symbol    **q;
  43.     int            attno, rel, found;
  44.     struct symbol        *cpsym(), *xc;
  45.  
  46. #    ifdef xOTR1
  47.     if (tTf(81, 0))
  48.         printf("FINDSIMPS\n");
  49. #    endif
  50.     De.ov_nsimp = 0;
  51.     found = FALSE;
  52.     q = De.ov_qlist;    /* q holds pointer to qualification */
  53.  
  54.     if (!q)
  55.         return (0);
  56.  
  57.  
  58.     for (t = (*q)->type; t != QLEND; t = (*++q)->type)
  59.     {
  60.         switch (t)
  61.         {
  62.           case VAR:
  63.             attno = (*q)->value.sym_var.attno;    /* save att number */
  64.             t = (*++q)->type;
  65.             if (t == INT || t == FLOAT || t == CHAR || t == S_VAR)
  66.             {
  67.                 c = *q;    /* save pointer to value symbol */
  68.                 t = (*++q)->type;
  69.                 if ((rel = relop(*q, FALSE)) >= 0 
  70.                    && (t = (*++q)->type) == AND)
  71.                 {
  72.                     /* found a simple clause */
  73.                     found = TRUE;
  74.                 }
  75.             }
  76.             break;
  77.  
  78.           case S_VAR:
  79.           case INT:
  80.           case FLOAT:
  81.           case CHAR:
  82.             c = *q++;
  83.             if ((t = (*q)->type) == VAR)
  84.             {
  85.                 attno = (*q)->value.sym_var.attno;
  86.                 t = (*++q)->type;
  87.                 if ((rel = relop(*q, TRUE)) >= 0 && (t = (*++q)->type) == AND)
  88.                 {
  89.                     /* found a simple clause */
  90.                     found = TRUE;
  91.                 }
  92.             }
  93.         }
  94.         if (found)
  95.         {
  96.             /* a simple clause has been found.
  97.             ** Check that the constant contains
  98.             ** at least one char before any pattern
  99.             ** matching char. If there is a pattern
  100.             ** matching char then special processing
  101.             ** must be done.
  102.             */
  103.  
  104.             found = FALSE;
  105.             if (length = check(c))
  106.             {
  107.  
  108.                 /*
  109.                 ** If length is zero then the first char was
  110.                 ** a pattern matching char. If length < 0 then
  111.                 ** no pattern matching char, and finally
  112.                 ** if length > 0 then length is the number of
  113.                 ** chars before the first pattern matching char
  114.                 */
  115.                 if (length > 0)
  116.                 {
  117.                     switch (rel)
  118.                     {
  119.  
  120.                       case opEQ:
  121.                         /*
  122.                         ** Create two simple clauses:
  123.                         ** One below the value and the
  124.                         ** other above the value.
  125.                         */
  126.                         xc = cpsym(c, length, opLTLE);
  127.                         add_simp(xc, opLTLE, attno);
  128.                         rel = opGTGE;
  129.                         /* fall through to GTGE case */
  130.  
  131.                       case opGTGE:
  132.                         c = cpsym(c, length, opGTGE);
  133.                         break;
  134.  
  135.                       case opLTLE:
  136.                         c = cpsym(c, length, opLTLE);
  137.                         break;
  138.                     }
  139.                 }
  140.  
  141.                 if (add_simp(c, rel, attno))
  142.                     break;    /* no more room in simps */
  143.             }
  144.         }
  145.         while (t != AND)    /* skip to next AND */
  146.             t = (*++q)->type & I1MASK;
  147.     }
  148. #    ifdef xOTR1
  149.     if (tTf(81, 2))
  150.         printf("findsimps returning %d\n", De.ov_nsimp);
  151. #    endif
  152.     return (De.ov_nsimp);
  153. }
  154.  
  155.  
  156. /*
  157. **    relop determines whether a symbol is a
  158. **    usable relational operator ie. =,>,>=,<,<=
  159. **
  160. **    returns the type of the relational
  161. **    operator if found, else it returns
  162. **    -1
  163. **
  164. **    Items are normalized to be in the form:
  165. **    var relop constant. If reverse is TRUE then
  166. **    complement the sense of the relop. Reverse will
  167. **    be TRUE is the simple clause was found in the
  168. **    form constant relop var.
  169. */
  170. relop(s, reverse)
  171. struct symbol    *s;
  172. int        reverse;
  173. {
  174.     register int    v;
  175.  
  176.     v = -1;    /* assume failure */
  177.     if (s->type == BOP)
  178.     {
  179.         switch (s->value.sym_op.opno)
  180.         {
  181.  
  182.           case opEQ:
  183.             v = opEQ;
  184.             break;
  185.  
  186.           case opLT:
  187.           case opLE:
  188.             v = opLTLE;
  189.             if (reverse)
  190.                 v = opGTGE;
  191.             break;
  192.  
  193.           case opGT:
  194.           case opGE:
  195.             v = opGTGE;
  196.             if (reverse)
  197.                 v = opLTLE;
  198.             break;
  199.  
  200.         }
  201.     }
  202.     return (v);
  203. }
  204.  
  205.  
  206.  
  207. /*
  208. **    check checks the symbol for
  209. **    pattern matching characters.
  210. **    If any are found then check returns
  211. **    the number of characters before the
  212. **    first pattern matching character.
  213. **
  214. **    If no pattern matching chars are found
  215. **    then check returns -1.
  216. **
  217. **    note that PAT_RBRAC need not be checked for
  218. **    since it is not a pattern matching char unless
  219. **    PAT_LBRAC appears before it.
  220. **
  221. **    PAT_LBRAC is treated specially in cpsym().
  222. **    If any are detected, then length until the
  223. **    first PAT_ANY or PAT_ONE or PAT_SPEC is returned.
  224. */
  225. check(sym)
  226. struct symbol    *sym;
  227. {
  228.     register struct symbol    *s;
  229.     register char        *cp;
  230.     register int        len;
  231.     int            flag;
  232.  
  233.     s = sym;
  234. #    ifdef xOTR1
  235.     if (tTf(81, 4))
  236.     {
  237.         printf("Checksym:");
  238.         prsym(s);
  239.     }
  240. #    endif
  241.     if (s->type == CHAR)
  242.     {
  243.         flag = FALSE;
  244.         cp = s->value.sym_data.c0type;    /* the string is a literal */
  245.         len = s->len & I1MASK;
  246.         while (len--)
  247.         {
  248.             switch(*cp++)
  249.             {
  250.  
  251.               case PAT_ANY:
  252.               case PAT_ONE:
  253.               case PAT_SPEC:
  254.                 return ((s->len & I1MASK) - len - 1);
  255.  
  256.               case PAT_LBRAC:
  257.                 flag = TRUE;
  258.  
  259.             }
  260.         }
  261.         if (flag)
  262.             return (s->len & I1MASK);    /* constant had PAT_LBRAC char */
  263.     }
  264.     return (-1);    /* ok */
  265. }
  266.  
  267.  
  268. /*
  269. ** Cpsym -- copy a symbol to a new buffer area.
  270. **    If op is opLTLE then add a pad character
  271. **    whose value is the largest possible char
  272. **    value.
  273. **
  274. **    If any ranges of characters are found,
  275. **    then the lowest/highest char is taken from
  276. **    range.
  277. */
  278.  
  279. struct symbol 
  280. *cpsym(cons, len, op)
  281. struct symbol    *cons;
  282. int        len;
  283. int        op;
  284. {
  285.     register struct symbol    *s;
  286.     register char        *cp;
  287.     register int        i;
  288.     char            *sp, c, nc;
  289.     extern char        *ov_ovqpbuf;
  290.     char            *need();
  291.  
  292.     i = len;
  293.     s = (struct symbol *)
  294.         need(De.ov_ovqpbuf, op == opLTLE ? i + SYMOFF+1 : i + SYMOFF);
  295.     s->type = CHAR;
  296.     sp = s->value.sym_data.c0type;
  297.     cp = cons->value.sym_data.c0type;
  298.  
  299.     while (i--)
  300.     {
  301.         /* copy chars processing LBRAC chars if any */
  302.         if ((c = *cp++) == PAT_LBRAC)
  303.         {
  304.             /* if string is empty, ignore it */
  305.             if (i == 0)
  306.                 break;
  307.  
  308.             c = *cp++;
  309.             i--;
  310.  
  311.             if (c == PAT_RBRAC)
  312.                 continue;    /* empty [] */
  313.  
  314.             while (i-- && ((nc = *cp++) != PAT_RBRAC))
  315.             {
  316.                 /* ignore '-' */
  317.                 if (nc == '-')
  318.                     continue;
  319.  
  320.                 /* check for char larger/smaller than 'c' */
  321.                 if (op == opLTLE)
  322.                 {
  323.                     if (nc > c)
  324.                         c = nc;
  325.                 }
  326.                 else
  327.                 {
  328.                     if (nc < c)
  329.                         c = nc;
  330.                 }
  331.             }
  332.         }
  333.  
  334.         *sp++ = c;    /* copy next char */
  335.     }
  336.     if (op == opLTLE)
  337.         *sp++ = 0177;
  338.     s->len = sp - s->value.sym_data.c0type;
  339.  
  340.     return (s);
  341. }
  342.  
  343.  
  344.  
  345. /*
  346. ** Add_simp -- add a simple clause to the list of
  347. **    simple clauses. As a side effect the De.ov_nsimp
  348. **    is incremented. If there is no room return
  349. **    TRUE else return FALSE
  350. */
  351.  
  352. add_simp(cons, rel, attno)
  353. struct symbol    *cons;
  354. int        rel;
  355. int        attno;
  356. {
  357.     register struct simp    *s;
  358.  
  359.     if (De.ov_nsimp == NSIMP)
  360.         return (TRUE);    /* no more room */
  361.  
  362.     s = &De.ov_simp[De.ov_nsimp++];
  363.  
  364.     s->att = attno;
  365.     s->cons = cons;
  366.     s->relop = rel;
  367.  
  368. #    ifdef xOTR1
  369.     if (tTf(81, 3))
  370.         prsimp(s);
  371. #    endif
  372.  
  373.     return (FALSE);
  374. }
  375.  
  376.  
  377. prsimp(ss)
  378. struct simp    *ss;
  379. {
  380. #    ifdef xOTR1
  381.     struct simp    *s;
  382.  
  383.     s = ss;
  384.     printf("simp:relop=%d,att=%d,val=", s->relop, s->att);
  385.     prsym(s->cons);
  386. #    endif
  387. }
  388.